home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-29 | 7.4 KB | 357 lines | [TEXT/CWIE] |
- #include "TreeNode.h"
- #include <stdio.h>
-
- TreeNode::TreeNode(void* theKey)
- {
- fNodeKey = theKey;
- fNodeData = nil;
-
- fParent = nil;
- fLeftChild = nil;
- fRightChild = nil;
-
- fLeftChildCount = 0;
- fRightChildCount = 0;
- }
-
-
- TreeNode::TreeNode(void* theKey, void* theData)
- {
- fNodeKey = theKey;
- fNodeData = theData;
-
- fParent = nil;
- fLeftChild = nil;
- fRightChild = nil;
-
- fLeftChildCount = 0;
- fRightChildCount = 0;
-
- }
-
-
- TreeNode::~TreeNode(void)
- {
-
- }
-
-
- // Insert node is non-recursive. Doing it this way simplifies the code since I
- // need to find the rood before doing insertion. This allows any node in the
- // tree to take a new key and data for insertion, instead of limiting the insertion
- // to start only from the root of the entire tree. This allows us to guarantee that
- // the key remians unique to the entire tree.
- // Override this method if you want non-unique keys, or a different insertion order.
- TreeNode* TreeNode::InsertNode(void* theKey, void* theData)
- {
- TreeNode* currentNode;
- TreeNode* newNode;
- short howToGo;
- Boolean insertFound = false;
-
- if (fParent == nil)
- currentNode = this;
- else
- currentNode = this->GetRoot();
-
- printf("TreeRoot = %d\n", (long) currentNode->GetNodeKey());
-
- while (!insertFound)
- {
- howToGo = currentNode->CompareToNodeKey(theKey);
- if (howToGo < 0) // The new key is smaller than the node key, check left
- {
- if (currentNode->fLeftChild != nil)
- {
- currentNode = currentNode->fLeftChild;
- printf("Moving left to node %d\n", (long) currentNode->GetNodeKey());
- }
- else { // Insert it to the left
- printf("inserting on left\n");
- insertFound = true;
- howToGo = -1; // Tell me to insert to the left of the current node
- }
- }
- else if (howToGo > 0)
- {
- if (currentNode->fRightChild != nil)
- {
- currentNode = currentNode->fRightChild;
- printf("Moving right to node %d\n", (long) currentNode->GetNodeKey());
- }
- else { // Insert it to the right
- printf("inserting on right\n");
- insertFound = true;
- howToGo = 1; // Tell me to insert to the left of the current node
- }
- }
- }
-
- if (howToGo == 0) // if 0, we found an identical key and don't want to insert
- {
- newNode = nil;
- }
- else {
- newNode = new TreeNode(theKey, theData);
- if (howToGo < 0)
- currentNode->fLeftChild = newNode;
- else
- currentNode->fRightChild = newNode;
-
- newNode->fParent = currentNode;
-
- // Now the last thing to do is to propagate the addition upwards in the counts
- currentNode->fLeftChildCount++; // Goes from 0 to 1
- while (currentNode != nil)
- {
- if (currentNode->fParent != nil)
- {
- if (currentNode->fParent->fLeftChild == currentNode) // up the left child count
- currentNode->fParent->fLeftChildCount++;
- else
- currentNode->fParent->fRightChildCount++;
- }
-
- currentNode = currentNode->fParent;
- }
- }
-
- return (newNode);
- }
-
-
-
- void* TreeNode::GetNodeKey(void)
- {
- return (fNodeKey);
- }
-
-
- void* TreeNode::GetNodeData(void)
- {
- return (fNodeData);
- }
-
-
- void TreeNode::SetNodeData(void* theData)
- {
- fNodeData = theData;
- }
-
-
-
- TreeNode* TreeNode::FindKeyNode(void* searchKey)
- {
- TreeNode* theNode = GetRoot();
- short result;
-
- while (theNode != nil)
- {
- result = theNode->CompareToNodeKey(searchKey);
- if (result == 0) // Found it, so just return the current node
- return (theNode);
- else if (result < 0) // Check the left side branch
- theNode = theNode->fLeftChild;
- else // Otherwise try the right branch
- theNode = theNode->fRightChild;
- }
-
- return (theNode); // If we ran out of nodes without matching
- // this returns nil;
- }
-
-
- // This code is essentially identical to FindKeyNode, but if somebody
- // wants to override it for some specific purpose, they can.
- TreeNode* TreeNode::FindDataNode(void* searchData) // Returns FIRST instance of searchData
- {
- TreeNode* theNode = GetRoot();
- short result;
-
- while (theNode != nil)
- {
- result = theNode->CompareToNodeData(searchData);
- if (result == 0) // Found it, so just return the current node
- return (theNode);
- else if (result < 0) // Check the left side branch
- theNode = theNode->fLeftChild;
- else // Otherwise try the right branch
- theNode = theNode->fRightChild;
- }
-
- return (theNode); // If we ran out of nodes without matching
- // this returns nil;
-
- }
-
-
- long TreeNode::GetChildCount(void)
- {
- return (fLeftChildCount + fRightChildCount);
- }
-
-
- long TreeNode::GetLeftChildCount(void)
- {
- return (fLeftChildCount);
- }
-
-
- long TreeNode::GetRightChildCount(void)
- {
- return (fRightChildCount);
- }
-
-
-
- TreeNode* TreeNode::GetFirstNode(void)
- {
- TreeNode* leftmostNode;
-
- if (fParent == nil)
- leftmostNode = GetLeftmostSubNode();
- else
- leftmostNode = GetRoot()->GetLeftmostSubNode();
-
- return (leftmostNode);
- }
-
- // Return the next node in key order. We know that there are no unprocessed left children
- // for this node (since we are in-order) but there may be right children. If there
- // is a right child we need to move down its leftmost side
- TreeNode* TreeNode::GetNextNode(void)
- {
- TreeNode* targetNode;
- TreeNode* curNode = nil;
- Boolean foundIt = true;
-
- // We know that this node has already been returned. So return a right
- // right branch leftmost branch
- if (fRightChild != nil)
- {
- printf("getting right child subnode\n");
- targetNode = fRightChild->GetLeftmostSubNode();
- }
- else { // No right child, move up and see if we were the right child
- curNode = this;
- foundIt = false;
- while (foundIt == false)
- {
- if (curNode->fParent == nil) // We were at the root of the tree, and no right node
- {
- targetNode = nil; // Nothing move to traverse
- foundIt = true;
- }
- else {
- if (curNode->fParent->fRightChild == curNode) // We were the right child
- {
- curNode = curNode->fParent;
- printf("this was right child, moving up to parent\n");
- }
- else { // We were the left child, return the parent now
- curNode = curNode->fParent;
- printf("Moving up to parent %d\n", (long) curNode->GetNodeKey());
- targetNode = curNode; // ->GetNextNode();
- foundIt = true;
- }
- }
- }
- }
- return (targetNode);
- }
-
-
- TreeNode* TreeNode::GetPreviousNode(void)
- {
-
- }
-
-
- TreeNode* TreeNode::GetRoot(void)
- {
- TreeNode* aNode = this;
-
- while (aNode->fParent != nil)
- aNode = aNode->fParent;
-
- return (aNode);
- }
-
-
- void TreeNode::PruneBranch(void) // Remove this branch and sub-branches from the tree.
- {
- if (fParent->fLeftChild == this)
- fParent->fLeftChild = nil;
- else
- fParent->fRightChild = nil;
- }
-
-
- TreeNode* TreeNode::GetLeftmostSubNode(void)
- {
- TreeNode* curNode = this;
-
- while (curNode->fLeftChild)
- {
- curNode = curNode->fLeftChild;
- }
-
- return (curNode);
- }
-
-
- void TreeNode::InsertChildLeft(TreeNode *nodePtr)
- {
-
- }
-
-
- void TreeNode::InsertChildRight(TreeNode *nodePtr)
- {
-
- }
-
-
- void TreeNode::DeleteChildLeft()
- {
-
- }
-
-
- void TreeNode::DeleteChildRight()
- {
-
- }
-
-
- // Returns -1 if compareData < fNodeData, 0 if equal, and 1 if compareData > fNodeData
- // For the reusable class, I'm abusing void* and using it to hold a long value
- short TreeNode::CompareToNodeKey(void* compareKey)
- {
- short result;
-
- if (compareKey < fNodeKey)
- result = -1;
- else if (compareKey > fNodeKey)
- result = 1;
- else
- result = 0;
-
- return (result);
- }
-
-
- short TreeNode::CompareToNodeData(void* compareData)
- {
- short result;
-
- if (compareData < fNodeData)
- result = -1;
- else if (compareData > fNodeData)
- result = 1;
- else
- result = 0;
-
- return (result);
- }
-